#include "sdl_world.h"

namespace sdl_graphic {

camera::camera(const std::string & n) : sdl_layer(100, n)
{
    transform.id();
    los = mvector3f(0.0, 0.0, 1.0);
    up = mvector3f(0.0, 1.0, 0.0);
}

void camera::update()
{
    transform = translation(position);
    transform *= columns(up^los, up, los);

}


///obrót wokół linii optycznej

void camera::roll(const float & a)
{
    up = rotation(los, a) * up;
}

///obrót wokół osi pionowej

void camera::yaw(const float & a)
{
    los = rotation(up, a) * los;
}

///obrót wokół osi "w prawo" (wahanie góra/dół)

void camera::pitch(const float & a)
{
    matrix4x4f R = rotation(up^los, a);
    up = R*up;
    los = R*los;
}

///poruszanie się zgodnie z los

void camera::move_forward(const float & a)
{
    position += -(los / los.norm()) * a;
}

void camera::move_backward(const float & a)
{
    move_forward(-a);
}

///poruszanie się wzdłuż osi do góry

void camera::move_up(const float &a)
{
    position += -(up / up.norm()) * a;
}

void camera::move_down(const float &a)
{
    move_up(-a);
}

void camera::move_right(const float &a)
{
    position += -((up^los) / (los^up).norm()) * a;
}

void camera::move_left(const float &a)
{
    move_right(-a);
}

void camera::rotate(const mvector3f & n, const float & a)
{
    matrix4x4f R = rotation(n, a);
    up = R*up;
    los = R*los;
}

void camera::translate(const mvector<float, 3 > & a)
{
    position += a;
}

void camera::reset()
{
    position.zero();
    transform.id();
}

matrix4x4f camera::get_transform()
{
    return transform;
}

mvector3f camera::get_up()
{
    return up;
}

mvector3f camera::get_los()
{
    return los;
}

mvector3f camera::get_right()
{
    return up^los;
}

mvector3f camera::get_position()
{
    return position;
}

}; //namespace sdl_graphic
